package vista;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import javax.swing.JPanel;

import controlador.AdministradorDeEvaluaciones;

import modelo.Observado;
import modelo.Observador;
import modelo.abstraccionesGeometricas.Punto;
import modelo.funciones.Redondear;

public class VistaGraficador extends JPanel implements ActionListener, Observador {
	
	private List<List<Punto>> puntos;
	private static double ESCALA = 1;
	private static int step = 33;
	
	public VistaGraficador(){
		this.setPuntos(new ArrayList<List<Punto>>());
		super.setSize(500, 500);
	}
	
	private void dibujarLosEjes(Graphics g,int centroY,int centroX){
		
		int MasInfinitoX = (int)(this.getWidth()/2);
		int MasInfinitoY = (int)(this.getHeight()/2);
		
		g.setColor(Color.BLACK);
		g.drawLine(0,centroY,centroX*2,centroY);
		g.drawLine(centroX,0,centroX,centroY*2);
		for (int i = 1; i<MasInfinitoX; i++) {
			int x = obtenerPosicionX1(i,centroX);
			g.drawLine(x, centroY+8, x, centroY-8);
			g.drawString((new Double(Redondear.redondear(i*ESCALA))).toString(),x , centroY-10);
			int menosX = obtenerPosicionX1(-i,centroX);
			g.drawLine(menosX, centroY+8, menosX, centroY-8);
			g.drawString((new Double(Redondear.redondear(-i*ESCALA))).toString(),menosX , centroY-10);
			
		}
		for (int i = 1; i<MasInfinitoY; i++) {
			int y = obtenerPosicionY1(i,centroY);
			g.drawLine(centroX+8, y, centroX-8, y);
			g.drawString((new Double(Redondear.redondear(i*ESCALA))).toString(), centroX-10, y);
			int menosY = obtenerPosicionY1(-i,centroY);
			g.drawLine(centroX+8, menosY, centroX-8, menosY);
			g.drawString((new Double(Redondear.redondear(-i*ESCALA))).toString(), centroX-10, menosY);
		}
		
	}
	
	private int obtenerPosicionX(double x, int centroX) {
		return (int)(centroX + (x/ESCALA)*step);
	}
	
	private int obtenerPosicionY(double y, int centroY) {
		return (int)(centroY - (y/ESCALA)*step);
	}
	private int obtenerPosicionX1(double x, int centroX) {
		return (int)(centroX + x*step);
	}
	
	private int obtenerPosicionY1(double y, int centroY) {
		return (int)(centroY - y*step);
	}
	
	public void graficarPuntos(Graphics g, List<Punto> puntos) {
		g.setColor(Color.red);
		int centroX=(this.getSize().width)/2;
		int centroY=(this.getSize().height)/2;
		Iterator<Punto> it = puntos.iterator();
		Punto punto1 = it.next();
		while (it.hasNext()) {
			
			int x1,y1,x2,y2;
			try {
				Punto punto2 = it.next();
				x1 = obtenerPosicionX(punto1.getCoordenadaX(),centroX);
				y1 = obtenerPosicionY(punto1.getCoordenadaY(),centroY);
				x2 = obtenerPosicionX(punto2.getCoordenadaX(),centroX);
				y2 = obtenerPosicionY(punto2.getCoordenadaY(),centroY);
				g.drawLine(x1,y1,x2,y2);
				punto1 = punto2;
			}catch (Exception e) {}
		}
	}
	
	public void paintComponent(Graphics g) {
		
		super.paintComponent(g) ;
		int centroX=(this.getSize().width)/2;
		int centroY=(this.getSize().height)/2;
		
		
		this.dibujarLosEjes(g,centroY,centroX);
		ListIterator iterador=this.getPuntos().listIterator();
		while (iterador.hasNext()){
			List<Punto> vector = (List<Punto>)iterador.next();
			graficarPuntos(g,vector);
		}
	}
	
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() instanceof BotonObservador) {
			BotonObservador boton = (BotonObservador)e.getSource();
			if (boton.getText().equals("Reducir"))
				VistaGraficador.ESCALA = VistaGraficador.ESCALA*10;
			if (boton.getText().equals("Ampliar"))
				VistaGraficador.ESCALA = VistaGraficador.ESCALA/10;
 
			this.repaint();
		}
	}
	
	private void setPuntos(List<List<Punto>> puntos){
		this.puntos=puntos;
	}
	
	private List<List<Punto>> getPuntos(){
		return this.puntos;
	}

	public void update(Observado obs) {
		AdministradorDeEvaluaciones adm=(AdministradorDeEvaluaciones)obs;
		this.setPuntos(adm.getPuntos());
		this.repaint();	
	}
}
